package cn.hp.beauty.config;

import cn.hp.beauty.common.constant.JwtConstant;
import cn.hp.beauty.common.security.MyUserDetailsServiceImpl;
import cn.hp.beauty.domain.CheckResult;
import cn.hp.beauty.domain.Userinfo;
import cn.hp.beauty.service.UserinfoService;
import cn.hp.beauty.util.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;

public class JWTAuthenticationFilter extends BasicAuthenticationFilter {

    @Autowired
    private UserinfoService userinfoService;
    @Autowired
    private MyUserDetailsServiceImpl myUserDetailsService;

    private static final String URL_WHITELIST[] = {
            "/login",
            "/logout",
            "/captcha",
            "/password",
            "/image/**",
            "/test/**"
    };

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager, UserinfoService userinfoService, MyUserDetailsServiceImpl myUserDetailsService) {
        super(authenticationManager);
        this.userinfoService = userinfoService;
        this.myUserDetailsService = myUserDetailsService;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 获取请求中的token
        // 检查token是否有值，或者是否是白名单内的请求
        // token有值时，检验token是否可用
        // 如果可用，继续向下，如果不可用，返回错误信息

        String token = request.getHeader("token");

        if (token == null || new ArrayList<String>(Arrays.asList(URL_WHITELIST)).contains(request.getRequestURI())){
            chain.doFilter(request, response);
        }

        CheckResult checkResult = JwtUtil.validateJWT(token);
        if (!checkResult.isSuccess()){
            switch (checkResult.getErrCode()) {
                case JwtConstant.JWT_ERRCODE_NULL:
                    throw new JwtException("Token不存在");
                case JwtConstant.JWT_ERRCODE_EXPIRE:
                    throw new JwtException("Token已过期");
                case JwtConstant.JWT_ERRCODE_FAIL:
                    throw new JwtException("Token验证失败");

            }
        }

        Claims claims = JwtUtil.parseJWT(token);
        String username = claims.getSubject();
        Userinfo userinfo = userinfoService.findUserByUsername(username);
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userinfo.getUName(), userinfo.getUPwd(),myUserDetailsService.getUserAuth(userinfo.getUId()));
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        chain.doFilter(request, response);
    }

}
